#include "word_segmentation.hpp"
#include <mysql/mysql.h>
#include <unordered_map>
#include <unordered_set>
#include <unistd.h>
#include <fcntl.h>
#include <jsoncpp/json/value.h>
#include <jsoncpp/json/json.h>
#include <fstream>

struct All_News_Info{
    vector<string> ids;
    vector<string> titles;
    vector<string> authors;
    vector<string> contents;
    vector<string> dates;
};
//从数据库拿取数据
//数据来源是新闻的标题和内容
void SearchData(All_News_Info& infos){
    MYSQL* conn;
    conn = mysql_init(NULL);
    //设置连接的字符集为utf8，不然没法显示中文
    mysql_set_character_set(conn,"utf8");
    if(conn == NULL)
        cout << "Error " << mysql_errno(conn) << ": " << mysql_error(conn);
    if(mysql_real_connect(conn,"localhost","root","1","news",0,NULL,0) == NULL)
        cout << "Error " << mysql_errno(conn) << ": " << mysql_error(conn);

    MYSQL_RES* result;
    MYSQL_ROW row;
    
    mysql_query(conn,"select id,title,author,content,createdate from news");
    result = mysql_store_result(conn);
    while((row = mysql_fetch_row(result))){
        infos.ids.push_back(row[0]);
        infos.titles.push_back(row[1]);
        infos.authors.push_back(row[2]);
        infos.contents.push_back(row[3]);
        infos.dates.push_back(row[4]);
    }
}

//存储索引(正排索引和倒排索引)
//正排索引（文档id->文档的全部信息，用来查看文档中关键词的出现次数）
//根据关键词在不同文档中的出现次数，排序搜索结果，次数越高的关联越大）
//倒排索引（关键词->文档id，用来查看关键词在哪些文档中出现过）
void Save_index(const All_News_Info& infos){
    WordSegmentation wordSeg; 
    vector<string> results; 
    std::unordered_map<string,std::unordered_set<string>> inverted_index;
    std::unordered_map<string,std::unordered_map<string,string>> forward_index;
    for(size_t i = 0;i < infos.titles.size();++i){
        //把有关标题，作者和内容的分词结果放到倒排索引中
        results = wordSeg(infos.titles[i]);
        for(auto it:results)
            inverted_index[it].insert(infos.ids[i]);

        results = wordSeg(infos.contents[i]);
        for(auto it:results)
            inverted_index[it].insert(infos.ids[i]);

        results = wordSeg(infos.authors[i]);
        for(auto it:results)
            inverted_index[it].insert(infos.ids[i]);

        //把对应id下的所有信息放到正排索引中
        forward_index[infos.ids[i]]["title"] = infos.titles[i];
        forward_index[infos.ids[i]]["author"] = infos.authors[i];
        forward_index[infos.ids[i]]["content"] = infos.contents[i];
        forward_index[infos.ids[i]]["date"] = infos.dates[i];
    }

    //将json数据保存到文件中
    Json::Value root1,root2;
    for(auto it:inverted_index){
        string str = "";
        for(auto it2 :it.second)
            str += it2 + " ";
        root1[it.first] = str; 
    }
    for(auto it:forward_index){
        Json::Value partner;
        for(auto it2:it.second)
            partner[it2.first] = it2.second;
        root2[it.first] = partner;
    }
    
    Json::StyledWriter sw;
    std::ofstream os1,os2;
    os1.open("inverted_index.json");
    os2.open("forward_index.json");
    os1 << sw.write(root1);
    os2 << sw.write(root2);
    os1.close();
    os2.close();
}

int main(){
    All_News_Info infos;
    SearchData(infos);
    Save_index(infos);

    return 0;
}
